<script setup lang="ts">
import { quotaPointApi } from '@/api'

import type { FormInstance, FormRules } from 'element-plus'
import type { Directive } from 'vue'

const userStore = useUserStore()
const tanpanchaStore = useTanpanchaStore()

const formRef = ref<FormInstance>()
const form = reactive({
  date: `${new Date().getFullYear()}`,
  point: 0,
  carbonQuota: 0,
})
const rules: FormRules = {
  date: [
    { required: true, message: '请选择年份', trigger: 'change' },
  ],
  point: [
    { required: true, message: '请选择用能单元', trigger: 'change' },
  ],
  carbonQuota: [
    { required: true, message: '请输入碳配额', trigger: 'blur' },
  ],
}

const vLimit: Directive = {
  mounted(el, binding) {
    const { min, max, decimalPlaces, callback } = binding.value // 获取参数
    const inputElement = el.querySelector('input')

    // 定义一个函数，用于校验和修正输入值
    const validateInput = () => {
      let value = inputElement.value
      let numericValue = Number.parseFloat(value)
      const decimalRegex = new RegExp(`^\\d+(\\.\\d{0,${decimalPlaces}})?$`)

      // 如果为空，直接返回（允许清空输入框）
      if (value === '') {
        value = ''
      }
      else if (/^0\d/.test(value) && !/^0(\.\d+)?$/.test(value)) { // 移除前导零（除非它是 "0" 或 "0.xxx" 的形式）
        value = value.replace(/^0+/, '') // 移除所有前导零，除非它是单个零或小数
        if (value === '')
          value = '0' // 如果移除后为空，则设为 '0'
      }
      else if (Number.isNaN(numericValue) || /[^0-9.]/.test(value)) { // 尝试将输入值转换为数字（处理可能的非法输入）
        numericValue = 0 // 如果无法解析为数字，则重置为 0
        value = 0
      }
      else if (!decimalRegex.test(value)) { // 限制小数位数
        // 如果小数位数超过限制，修正输入值
        const [integerPart, decimalPart] = value.split('.')
        if (decimalPart) {
          value = `${integerPart}.${decimalPart.slice(0, decimalPlaces)}`
        }
        else {
          value = integerPart
        }
        numericValue = Number.parseFloat(value) // 更新解析后的数值
      }

      // 限制范围
      if (numericValue < min) {
        numericValue = min
        value = min.toString()
      }
      else if (numericValue > max) {
        numericValue = max
        value = max.toString()
      }

      // 修正输入框的值（仅更新 DOM，不触发 v-model）
      if (inputElement.value !== value) {
        inputElement.value = value
      }

      // 手动更新 v-model 的值（通过 vnode.context）
      if (callback) {
        callback(value)
      }
    }

    // 监听输入事件
    inputElement.addEventListener('input', validateInput)
  },
}

async function getInfo() {
  if (!form.date || !form.point) {
    form.carbonQuota = 0
    return
  }
  const { data } = await quotaPointApi.queryQuotaInfoOfPoint(
    form.point,
    +form.date,
  )
  form.carbonQuota = data.quantity ?? 0
}
async function saveInfo() {
  formRef.value?.validate(async (valid) => {
    if (valid) {
      await quotaPointApi.saveQuotaInfoOfPoint({
        pointId: form.point,
        year: +form.date,
        quantity: form.carbonQuota,
      })
      ElMessage.success('保存成功')
    }
  })
}

async function handleClickNode(node: any) {
  form.point = node.id
}

watchEffect(async () => {
  await getInfo()
})
</script>

<template>
  <div class="padding-sm flex container">
    <ReadonlyPointTree
      fire
      :need-full-name="1"
      class="flex-incompressible"
      @click-node="handleClickNode"
    />
    <div class="ml-4 flex-auto">
      <ElForm ref="formRef" class="w-100" :rules="rules" :model="form" label-width="80px">
        <ElFormItem label="选择年份" prop="date">
          <ElDatePicker
            v-model="form.date"
            type="year"
            placeholder="选择年份"
            value-format="YYYY"
            format="YYYY"
          />
        </ElFormItem>
        <ElFormItem label="用能单元" prop="point">
          <div>{{ userStore.getPointNameById(form.point) }}</div>
        </ElFormItem>
        <ElFormItem label="碳配额" prop="carbonQuota">
          <ElInput
            v-model="form.carbonQuota"
            v-limit="{ min: 0, max: 999999999, decimalPlaces: 6 }" :clearable="false" type="number"
          >
            <template #suffix>
              {{ tanpanchaStore.panchaUnit }}
            </template>
          </ElInput>
        </ElFormItem>
        <ElFormItem>
          <ElButton type="primary" @click="saveInfo">
            保存
          </ElButton>
        </ElFormItem>
      </ElForm>
    </div>
  </div>
</template>
